package JET;

import JET.Centers.ControlCenter;
import JET.Actions.Action;
import JET.Actions.ActivateTorquesAction;
import JET.Actions.DeactivateTorquesAction;
import JET.Centers.Graphics.GUICenter.UtilTabs;
import JET.VirtualKeyboard.VKey;
import JET.Frames.DataModels.DataModelsFactory;
import JET.Frames.DataModels.SceneTreeModel;

import JET.SA.SA_Dialogs;
import JET.SA.SA_Mass;
import JET.SA.SA_RSpring;
import JET.SA.SA_Selection;
import JET.SA.SA_Spring;
import JET.SA.SA_Wall;
import JET.SwingUtils.TreeUtil;
import JET.UtilPanels.UPSceneInspector;
import JET.physics.bodies.SpringBody;
import JET.geom.Vec2d;
import JET.graphics.elements.Face;
import JET.physics.engine.JETContext;
import java.util.ArrayList;

import JET.physics.Mass;
import JET.physics.MaterialPair;
import JET.physics.RSpring;
import JET.physics.Spring;
import JET.physics.steering.Torque;
import JET.physics.Wall;
import JET.physics.interfaces.SceneTreeNode;
import java.util.Collection;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

/**
 *
 * @author 057Ry
 */
public class StaticActions implements Constants {

    static final ControlCenter CC = ControlCenter.getInstance();

//    ////////////////////////////////////////////////////////////////////////////
//    //                        S P R I N G   B O D Y                           //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static SpringBody addSpringBodyToScene(Scene scene, boolean updateSceneTreeSelection) {
//        SpringBody sb = new SpringBody();
//        scene.getEngine().addSpringBody(sb);
//
//        if (updateSceneTreeSelection) DataModelsFactory.getSceneTreeModel().fireSpringBodyListChanged();
//        StaticActions.setActualSpringBody(sb, scene, updateSceneTreeSelection);
//
//        return sb;
//    }
//
//    public static SpringBody addSpringBodyToScene(SpringBody sb, Scene scene, boolean updateSceneTreeSelection) {
//        if (sb != null) {
//            //scene.getEngine().addSpringBody(sb);
//            scene.getEngine().addSpringBody(sb);
//            if (updateSceneTreeSelection) DataModelsFactory.getSceneTreeModel().fireSpringBodyListChanged();
//            StaticActions.setActualSpringBody(sb, scene, updateSceneTreeSelection);
//            return sb;
//        } else {
//            return null;
//        }
//    }
//
//    public static void removeSpringBody(SpringBody sb, Scene scene) {
//        if (sb != null) {
//            // Removeing Walls from selection
//            for (Wall wall : sb.getBorder().getWallList()) {
//                if (scene.EC.selectionGroup.getWallList().contains(wall)) {
//                    StaticActions.removeWallFromSelection(wall, scene, true);
//                }
//            }
//
//            // Removeing Springs from selection
//            for (Spring spring : sb.getSpringList()) {
//                if (scene.EC.selectionGroup.getSpringList().contains(spring)) {
//                    StaticActions.removeSpringFromSelection(spring, scene, true);
//                }
//            }
//
//            // Removeing Rotary Springs from selection
//            for (RSpring rSpring : sb.getRSpringList()) {
//                if (scene.EC.selectionGroup.getRSpringList().contains(rSpring)) {
//                    StaticActions.removeRSpringFromSelection(rSpring, scene, true);
//                }
//            }
//
//            // Removeing masses from selection
//            Collection<Mass> massCol = sb.getMassListSync();
//            synchronized(massCol) {
//                for (Mass mass : massCol) {
//                    if (scene.EC.selectionGroup.getMassList().contains(mass)) {
//                        StaticActions.removeMassFromSelection(mass, scene, true);
//                    }
//                }
//            }
//
//            // Remove spring body from engine
//            scene.getEngine().removeSpringBody(sb);
//
//            // If thera are no more spring bodies in the endgine do apropriate stuff with editor
//            if (scene.getEngine().getSpringBodyList().isEmpty()) {
//                SpringBody.zeroSBCount();
//                StaticActions.setActualSpringBody(null, scene, true);
//            } // In other case, set next sb to be actual spring body that editor works on
//            else {
//                SpringBody asb = scene.getEngine().getSpringBodyList().get(scene.getEngine().getSpringBodyList().size() - 1);
//                StaticActions.setActualSpringBody(asb, scene, true);
//            }
//
//        }
//    }

//    ////////////////////////////////////////////////////////////////////////////
//    //                             M A S S                                    //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static void addMassToSpringBody(Mass mass, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addMass(mass);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }
//
//    public static void removeMassFromSpringBody(Mass mass, Scene scene, boolean updateSceneTreeSelection) {
//
//        // Remove mass from torques
//        ArrayList<Torque> torqueList = scene.getEngine().getTorqueListThatUsesMass(mass);
//        ArrayList<Torque> t2rList = new ArrayList<Torque>();
//
//        if (torqueList != null)
//            for (Torque t : torqueList)
//                if (t.getMass().equals(mass))
//                    t2rList.add(t);
//                else
//                    t.getMassList().remove(mass);
//
//        for(Torque t : t2rList)
//            removeTorque(t, scene);
//
//        // Remove engine springs that uses mass
//        removeSpringsFromEngine(SceneHelper.getSpringListOfMass(scene, mass, true, false, false), scene);
//
//        // Remove spring body springs that uses mass
//        removeSpringsFromSpringBody(SceneHelper.getSpringListOfMass(scene, mass, false, true, false), scene, false);
//
//        // Remove spring body springs that uses mass
//        removeSpringsFromSceneItem(SceneHelper.getSpringListOfMass(scene, mass, false, false, true), scene, false);
//
//        // Remove engine rotary springs that uses mass
////        removeRSpringsFromEngine(scene.getEngine().getRSpringListOfMass(mass), scene);
//        removeRSpringsFromEngine(SceneHelper.getRSpringListOfMass(scene, mass, true, false, false), scene);
//
//        // Remove spring body rotary springs that uses mass
////        removeRSpringsFromSpringBody(scene.getEngine().getRSpringListOfMass(mass), scene, false);
//        removeRSpringsFromSpringBody(SceneHelper.getRSpringListOfMass(scene, mass, false, true, false), scene, false);
//
//        // Remove walls that uses mass
////        removeWallsFromSpringBody(scene.getEngine().getWallListOfMass(mass), scene, false);
//        removeWallsFromSpringBody(SceneHelper.getWallListOfMass(scene, mass), scene, false);
//
//        // Remove mass from springBodies
////        SpringBody sb = scene.getEngine().getSpringBodyThatOwnMass(mass);
//        SpringBody sb = SceneHelper.getSpringBodyThatOwnMass(scene, mass);
//
//        if (sb != null) {
//            SA_Selection.removeMassFromSelection(mass, scene, true);
//            sb.removeMass(mass);
//            if (updateSceneTreeSelection)
//                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    //public static void addMassListToSpringBody(ArrayList<Mass> massList, SpringBody sb, boolean updateSceneTreeSelection) {
//    public static void addMassListToSpringBody(Collection<Mass> massList, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addMasses(massList);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }

//    ////////////////////////////////////////////////////////////////////////////
//    //                           S P R I N G                                  //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static void addSpringToSpringBody(Spring spring, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addSpring(spring);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }
//
//    public static void removeSpringFromSpringBody(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
//        SpringBody sb = SceneHelper.getSpringBodyThatOwnSpring(scene, spring);
//
//        if (sb != null) {
//            SA_Selection.removeSpringFromSelection(spring, scene, true);
//            sb.removeSpring(spring);
//            if (updateSceneTreeSelection)
//                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    public static void removeSpringFromSceneItem(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
//        SceneItem si = SceneHelper.getSceneItemThatOwnSpring(scene, spring);
//
//        if (si != null) {
//            SA_Selection.removeSpringFromSelection(spring, scene, true);
//            si.springList.remove(spring);
////            if (updateSceneTreeSelection)
////                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    public static void removeSpringsFromSpringBody(ArrayList<Spring> springs, Scene scene, boolean updateSceneTreeSelection) {
//        for(Spring s : springs)
//            removeSpringFromSpringBody(s, scene, updateSceneTreeSelection);
//    }
//
//    public static void removeSpringsFromSceneItem(ArrayList<Spring> springs, Scene scene, boolean updateSceneTreeSelection) {
//        for(Spring s : springs)
//            removeSpringFromSceneItem(s, scene, updateSceneTreeSelection);
//    }
//
//    //public static void addSpringListToSpringBody(ArrayList<Spring> springList, SpringBody sb, boolean updateSceneTreeSelection) {
//    public static void addSpringListToSpringBody(Collection<Spring> springList, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addSprings(springList);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }

//    ////////////////////////////////////////////////////////////////////////////
//    //                          R S P R I N G                                 //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static void addRSpringToSpringBody(RSpring rSpring, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addRSpring(rSpring);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }
//    public static void removeRSpringFromSpringBody(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
////        SpringBody sb = scene.getEngine().getSpringBodyThatOwnRSpring(rSpring);
//        SpringBody sb = SceneHelper.getSpringBodyThatOwnRSpring(scene, rSpring);
//
//        if (sb != null) {
//            sb.removeRSpring(rSpring);
//            if (updateSceneTreeSelection)
//                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    public static void removeRSpringFromSceneItem(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
//        SceneItem si = SceneHelper.getSceneItemThatOwnRSpring(scene, rSpring);
//
//        if (si != null) {
//            SA_Selection.removeRSpringFromSelection(rSpring, scene, true);
//            si.rSpringList.remove(rSpring);
////            if (updateSceneTreeSelection)
////                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    public static void removeRSpringsFromSpringBody(ArrayList<RSpring> list, Scene scene, boolean updateSceneTreeSelection) {
//        for(RSpring rs : list)
//            StaticActions.removeRSpringFromSpringBody(rs, scene, updateSceneTreeSelection);
//
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyListChanged();
//    }
//
//    public static void removeRSpringsFromSceneItem(ArrayList<RSpring> rSprings, Scene scene, boolean updateSceneTreeSelection) {
//        for(RSpring rs : rSprings)
//            removeRSpringFromSceneItem(rs, scene, updateSceneTreeSelection);
//    }
//
//    public static void addRSpringListToSpringBody(ArrayList<RSpring> rSpringList, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addRSprings(rSpringList);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }

//    ////////////////////////////////////////////////////////////////////////////
//    //                               F A C E                                  //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static void addFaceToSpringBody(Face f, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addFace(f);
//    }
//
//    public static void removeFaceFromSpringBody(Face f, SpringBody sb, boolean uupdateSceneTreeSelection) {
//        sb.removeFace(f);
//    }

//    ////////////////////////////////////////////////////////////////////////////
//    //                              W A L L                                   //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public static void addWallToSpringlBody(Wall wall, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addWallToBorder(wall);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }
//
//    public static void removeWallFromSpringBody(Wall wall, Scene scene, boolean updateSceneTreeSelection) {
////        SpringBody sb = scene.getEngine().getSpringBodyThatOwnWall(wall);
//        SpringBody sb = SceneHelper.getSpringBodyThatOwnWall(scene, wall);
//
//        if (sb != null) {
//            SA_Selection.removeWallFromSelection(wall, scene, true);
//            sb.removeWallFromBorder(wall);
//            if (updateSceneTreeSelection)
//                DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        }
//    }
//
//    public static void removeWallsFromSpringBody(ArrayList<Wall> walls, Scene scene, boolean updateSceneTreeSelection) {
//        for(Wall w : walls)
//            removeWallFromSpringBody(w, scene, updateSceneTreeSelection);
//    }
//
//    public static void addWallListToSpringBody(Collection<Wall> wallList, SpringBody sb, boolean updateSceneTreeSelection) {
//        sb.addWallsToBorder(wallList);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//    }

    ////////////////////////////////////////////////////////////////////////////
    //                              W A L L                                   //
    ////////////////////////////////////////////////////////////////////////////

//    public synchronized static void flipSpringBodyHorizontally(SpringBody sb) {
//        Vec2d cv = sb.getCenterVec();
//        Collection<Mass> massCol = sb.getMassListSync();
//        synchronized(massCol) {
//            for (Mass mass : massCol) {
//                double dx = (cv.getX() - mass.getPosition().getX()) * 2.;
//                mass.getPosition().addX(dx);
//                mass.getForce().scaleX(-1);
//                mass.getVelocity().scaleX(-1);
//            }
//        }
//    }
//
//    public synchronized static void flipSpringBodyVertically(SpringBody sb) {
//        Vec2d cv = sb.getCenterVec();
//        Collection<Mass> massCol = sb.getMassListSync();
//        synchronized(massCol) {
//            for (Mass mass : massCol) {
//                double dy = (cv.getY() - mass.getPosition().getY()) * 2.;
//                mass.getPosition().addY(dy);
//                mass.getForce().scaleY(-1);
//                mass.getVelocity().scaleY(-1);
//            }
//        }
//    }
//
//    public synchronized static void rotateSpringBodyByAngle(SpringBody sb, double a) {
//        Mass tmpMass = new Mass(0, 0, 0);
//        Vec2d cv = sb.getCenterVec();
//
//        Collection<Mass> massCol = sb.getMassListSync();
//        synchronized(massCol) {
//            for (Mass mass : massCol) {
//                tmpMass.become(mass);
//                tmpMass.getPosition().sub(cv);
//                tmpMass.getPosition().rotate(a);
//                tmpMass.getPosition().add(cv);
//                mass.getPosition().become(tmpMass.getPosition());
//            }
//        }
//    }
//
//    public synchronized static SpringBody setActualSpringBody(SpringBody sb, Scene scene, boolean updateSceneTreeSelection) {
//        // Unselect actual spring body scene tree node
//        if (scene.EC.currentSpringBody!=null && updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            //SceneTreeNode node = scene.getEngine().sceneTreeNode;
//            SceneTreeNode node = DataModelsFactory.getSceneTreeModel().sceneRootNode;
//            TreePath path = new TreePath(new Object[]{  node,
//                                                        node.getChild(SceneTreeModel.SceneRootNode.NODE_INDEX_SPRING_BODIES),
//                                                        scene.EC.currentSpringBody
//                                                 });
//            upSceneInspector.getSceneTree().removeSelectionPath(path);
//        }
//
//        scene.EC.currentSpringBody = sb;
//
//        if (sb != null) {
//            SA_Dialogs.fillPropertiesDialogWithSpringBodyData(sb);
//            sb.updateBoundingArea();
//            if (CC.GUIC.materialsDialog!=null)
//                CC.GUIC.materialsDialog.setSelectedCell(sb.getMaterial(), sb.getMaterial());
//
//            if (updateSceneTreeSelection) {
//                UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//                //SceneTreeNode node = scene.getEngine().sceneTreeNode;
//                SceneTreeNode node = DataModelsFactory.getSceneTreeModel().sceneRootNode;
//                TreePath path = new TreePath(new Object[]{  node,
//                                                            node.getChild(SceneTreeModel.SceneRootNode.NODE_INDEX_SPRING_BODIES),
//                                                            sb
//                                                     });
//                //upSceneInspector.getSceneTree().addSelectionPath(path);
//            }
//
//            CC.GUIC.repaintAllSceneTabs();
//        }
//
//        return sb;
//    }
//
//    public synchronized static SpringBody setActualSpringBody(int index, Scene scene, boolean updateSceneTreeSelection) {
//        SpringBody sb = null;
//
//        if (index >= 0 && index < scene.getEngine().getSpringBodyList().size()) {
//            sb = scene.getEngine().getSpringBodyList().get(index);
//        }
//
//        if (sb != null) {
//            scene.EC.currentSpringBody = sb;
//            SA_Dialogs.fillPropertiesDialogWithSpringBodyData(sb);
//            CC.GUIC.materialsDialog.setSelectedCell(sb.getMaterial(), sb.getMaterial());
//
//            if (updateSceneTreeSelection) {
//                UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//                //SceneTreeNode node = scene.getEngine().sceneTreeNode;
//                SceneTreeNode node = DataModelsFactory.getSceneTreeModel().sceneRootNode;
//                TreePath path = new TreePath(new Object[]{  node,
//                                                            node.getChild(SceneTreeModel.SceneRootNode.NODE_INDEX_SPRING_BODIES),
//                                                            sb
//                                                     });
//                upSceneInspector.getSceneTree().addSelectionPath(path);
//            }
//        }
//
//        return sb;
//    }
//
//    public synchronized static void setSpringBodyName(SpringBody sb, String name, boolean updateSceneTreeSelection) {
//        sb.setName(name);
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyChanged(sb);
//        CC.GUIC.repaintAllSceneTabs();
//    }
//
//    public static void clearSpringBodies(Scene scene, boolean updateSceneTreeSelection) {
//        ArrayList<SpringBody> list = new ArrayList<SpringBody>(scene.getEngine().getSpringBodyList());
//        for (SpringBody sb : list) {
//            StaticActions.removeSpringBody(sb, scene);
//        }
//        list.clear();
//
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireSpringBodyListChanged();
//    }

    public static void clearEngineSprings(Scene scene, boolean updateSceneTreeSelection) {
        ArrayList<Spring> springList = new ArrayList<Spring>(scene.getJETContext().getSpringList());
        for (Spring s : springList) {
            SA_Spring.removeSpringFromEngine(s, scene);
        }
        springList.clear();

        if (updateSceneTreeSelection)
            DataModelsFactory.getSceneTreeModel().fireWholeTreeChanged();
    }

    public static void clearEngineRSprings(Scene scene, boolean updateSceneTreeSelection) {
        ArrayList<RSpring> rSpringList = new ArrayList<RSpring>(scene.getJETContext().getRSpringList());
        for (RSpring rs : rSpringList) {
            SA_RSpring.removeRSpringFromEngine(rs, scene);
        }
        rSpringList.clear();

        if (updateSceneTreeSelection)
            DataModelsFactory.getSceneTreeModel().fireWholeTreeChanged();
    }

    public static void clearActions() {
        ArrayList<Action> aList = new ArrayList<Action>(CC.AC.getActionList());
        for (Action a : aList) {
            StaticActions.removeAction(a);
        }
        aList.clear();
    }

    public static void clearTorques(Scene scene, boolean updateSceneTreeSelection) {
        ArrayList<Torque> torqueList = new ArrayList<Torque>(scene.getJETContext().getTorqueList());
        for (Torque t : torqueList) {
            StaticActions.removeTorque(t, scene);
        }
        torqueList.clear();

        if (updateSceneTreeSelection)
            DataModelsFactory.getSceneTreeModel().fireWholeTreeChanged();
    }

//    ////////////////////////////////////////////////////////////////////////////
//    //   SELECTION - adding and removing stuff to and from selection group    //
//    ////////////////////////////////////////////////////////////////////////////
//
//    public synchronized static void addSpringBodyToSelection(SpringBody sb, Scene scene, boolean updateSceneTreeSelection) {
//        Collection<Mass> massCol = sb.getMassListSync();
//        synchronized(massCol) {
//            for (Mass mass : massCol)
//                StaticActions.addMassToSelection(mass, scene, updateSceneTreeSelection);
//        }
//
//        for (Spring spring : sb.getSpringList()) {
//            StaticActions.addSpringToSelection(spring, scene, updateSceneTreeSelection);
//        }
//        for (RSpring rSpring : sb.getRSpringList()) {
//            StaticActions.addRSpringToSelection(rSpring, scene, updateSceneTreeSelection);
//        }
//        for (Wall wall : sb.getBorder().getWallList()) {
//            StaticActions.addWallToSelection(wall, scene, updateSceneTreeSelection);
//        }
//    }
//
//    public synchronized static void addMassToSelection(Mass mass, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addMass(mass);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(mass, scene));
//        }
//    }
//
//    public synchronized static void addMassesToSelection(Collection<Mass> massCol, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addMasses(massCol);
//
//        if (updateSceneTreeSelection) {
//            TreePath[] paths = new TreePath[massCol.size()];
//            int index = 0;
//
//            for(Mass m : massCol) {
//                paths[index++] = new TreePath(TreeUtil.getObjectPath(m, scene));
//            }
//
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPaths(paths);
//        }
//    }
//
//    public synchronized static void removeMassFromSelection(Mass mass, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.removeMass(mass);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(mass, scene));
//        }
//    }
//
//    public synchronized static void addSpringToSelection(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addSpring(spring);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(spring, scene));
//        }
//    }
//
//    public synchronized static void addSpringsToSelection(Collection<Spring> springsCol, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addSprings(springsCol);
//
//        if (updateSceneTreeSelection) {
//            TreePath[] paths = new TreePath[springsCol.size()];
//
//            int index = 0;
//            for(Spring s : springsCol) {
//                paths[index++] = new TreePath(TreeUtil.getObjectPath(s, scene));
//            }
//
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPaths(paths);
//        }
//    }
//
//    public synchronized static void removeSpringFromSelection(Spring spring, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.removeSpring(spring);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(spring, scene));
//        }
//    }
//
//    public synchronized static void addRSpringToSelection(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addRSpring(rSpring);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(rSpring, scene));
//        }
//    }
//
//    public synchronized static void removeRSpringFromSelection(RSpring rSpring, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.removeRSpring(rSpring);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(rSpring, scene));
//        }
//    }
//
//    public synchronized static void addWallToSelection(Wall wall, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.addWall(wall);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().addSelectionPath(TreeUtil.getObjectPath(wall, scene));
//        }
//    }
//
//    public synchronized static void removeWallFromSelection(Wall wall, Scene scene, boolean updateSceneTreeSelection) {
//        scene.EC.selectionGroup.removeWall(wall);
//
//        if (updateSceneTreeSelection) {
//            UPSceneInspector upSceneInspector = (UPSceneInspector) CC.GUIC.getUtilTab(UtilTabs.SceneInspector);
//            upSceneInspector.getSceneTree().removeSelectionPath(TreeUtil.getObjectPath(wall, scene));
//        }
//    }
//
//    public synchronized static void clearSelection(Scene scene) {
//        ArrayList<Mass> mlist = new ArrayList<Mass>(scene.EC.selectionGroup.getMassList());
//        for (Mass mass : mlist)
//            StaticActions.removeMassFromSelection(mass, scene, true);
//        mlist.clear();
//
//        ArrayList<Spring> slist = new ArrayList<Spring>(scene.EC.selectionGroup.getSpringList());
//        for (Spring spring : slist)
//            StaticActions.removeSpringFromSelection(spring, scene, true);
//        slist.clear();
//
//        ArrayList<RSpring> rslist = new ArrayList<RSpring>(scene.EC.selectionGroup.getRSpringList());
//        for (RSpring rSpring : rslist)
//            StaticActions.removeRSpringFromSelection(rSpring, scene, true);
//        rslist.clear();
//
//        ArrayList<Wall> wlist = new ArrayList<Wall>(scene.EC.selectionGroup.getWallList());
//        for (Wall wall : wlist)
//            StaticActions.removeWallFromSelection(wall, scene, true);
//        wlist.clear();
//
//        CC.GUIC.repaintAllSceneTabs();
//    }
//
//    public static void deleteSelectedObjects(Scene scene, boolean updateSceneTreeSelection) {
//
//        ArrayList<Wall> wlist = new ArrayList<Wall>(scene.EC.selectionGroup.getWallListSync());
//        for (Wall wall : wlist)
//            StaticActions.removeWallFromSpringBody(wall, scene, false);
//        wlist.clear();
//        Collection<Spring> springCol = scene.EC.selectionGroup.getSpringListSync();
//
//        ArrayList<Spring> slist = new ArrayList<Spring>(scene.EC.selectionGroup.getSpringList());
//        for (Spring spring : slist) {
//            switch(spring.getType()) {
//                case Engine:
//                    StaticActions.removeSpringFromEngine(spring, scene);
//                    break;
//                case SceneItem:
//                    StaticActions.removeSpringFromSceneItem(spring, scene, false);
//                    break;
//                case SpringBody:
//                    StaticActions.removeSpringFromSpringBody(spring, scene, false);
//                    break;
//            }
//        }
//        slist.clear();
//
//        ArrayList<RSpring> rslist = new ArrayList<RSpring>(scene.EC.selectionGroup.getRSpringListSync());
//        for (RSpring rs : rslist) {
//            switch(rs.getType()) {
//                case Engine:
//                    StaticActions.removeRSpringFromEngine(rs, scene);
//                    break;
//                case SceneItem:
//                    StaticActions.removeRSpringFromSceneItem(rs, scene, false);
//                    break;
//                case SpringBody:
//                    StaticActions.removeRSpringFromSpringBody(rs, scene, false);
//                    break;
//            }
//        }
//        rslist.clear();
//
//        ArrayList<Mass> mlist = new ArrayList<Mass>(scene.EC.selectionGroup.getMassList());
//        for (Mass mass : mlist) {
//            StaticActions.removeMassFromSpringBody(mass, scene, false);
//        }
//        mlist.clear();
//
//        StaticActions.clearSelection(scene);
//
//        if (updateSceneTreeSelection)
//            DataModelsFactory.getSceneTreeModel().fireWholeTreeChanged();
//    }
//
//    public synchronized static void zeroSelectedMassVelocities(Scene scene) {
//        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
//            mass.getVelocity().zero();
//        }
//    }
//
//    public synchronized static void randomSelectedMassVelocities(Scene scene) {
//        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
//            Vec2d random = Vec2d.getRandomVectorInCircle(100);
//            mass.setVelocity(random);
//        }
//    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Copying items/objects on the scene
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    /**
     * Copys selected items (masses, springs and walls) into given spring body.
     * Spring body that is destination for those items must be added to scene,
     * before anything is copied into it, becouse this code uses these methods :
     *      Actions.addMassListToSpringBody(massList, sb);
     *      Actions.addSpringListToSpringBody(springList, sb);
     *      Actions.addWallListToSpringBody(wallList, sb);
     *
     * @param sb destination spring body, that items are copied into.
     * @return returns given spring body, filled with selected items.
     */
    public static SpringBody copySelectedItemsIntoSpringBody(SpringBody sb, Scene scene) {
        ArrayList<Mass> massList = new ArrayList<Mass>(scene.EC.selectionGroup.getMassList().size());

        Collection<Mass> massCol = scene.EC.selectionGroup.getMassListSync();
        synchronized(massCol) {
            for (Mass mass : massCol) {
                massList.add(mass.clone());
            }
        }

        ArrayList<Spring> springList = new ArrayList<Spring>(scene.EC.selectionGroup.getSpringList().size());
        Collection<Spring> springCol = scene.EC.selectionGroup.getSpringListSync();
        synchronized(springCol) {
            for (Spring spring : springCol) {
                int mass1Index = scene.EC.selectionGroup.getMassList().indexOf(spring.getM1());
                int mass2Index = scene.EC.selectionGroup.getMassList().indexOf(spring.getM2());

                Spring newSpring = new Spring(massList.get(mass1Index),
                        massList.get(mass2Index),
                        Spring.Type.SpringBody,
                        spring.getStartLength());

                newSpring.setKs(spring.getKs());
                newSpring.setKd(spring.getKd());
                springList.add(newSpring);
            }
        }

        ArrayList<RSpring> rSpringList = new ArrayList<RSpring>(scene.EC.selectionGroup.getRSpringList().size());
        Collection<RSpring> rSpringCol = scene.EC.selectionGroup.getRSpringListSync();
        synchronized(rSpringCol) {
            for (RSpring rSpring : rSpringCol) {
                int mass1Index = scene.EC.selectionGroup.getMassList().indexOf(rSpring.getM1());
                int mass2Index = scene.EC.selectionGroup.getMassList().indexOf(rSpring.getM2());
                int mass3Index = scene.EC.selectionGroup.getMassList().indexOf(rSpring.getM3());

                RSpring newRSpring = new RSpring(massList.get(mass1Index),
                        massList.get(mass2Index),massList.get(mass3Index),
                        rSpring.getStartAngle(),
                        RSpring.Type.SpringBody);

                newRSpring.setKs(rSpring.getKs());
                newRSpring.setKd(rSpring.getKd());
                rSpringList.add(newRSpring);
            }
        }

        ArrayList<Wall> wallList = new ArrayList<Wall>(scene.EC.selectionGroup.getWallList().size());
        Collection<Wall> wallCol = scene.EC.selectionGroup.getWallListSync();
        synchronized(wallCol) {
            for (Wall wall : scene.EC.selectionGroup.getWallList()) {
                int mass1Index = scene.EC.selectionGroup.getMassList().indexOf(wall.getM1());
                int mass2Index = scene.EC.selectionGroup.getMassList().indexOf(wall.getM2());

                Wall newWall = new Wall(massList.get(mass1Index), massList.get(mass2Index));
                wallList.add(newWall);
            }
        }

        SA_Mass.addMassListToSpringBody(massList, sb, false);
        SA_Spring.addSpringListToSpringBody(springList, sb, false);
        SA_RSpring.addRSpringListToSpringBody(rSpringList, sb, false);
        SA_Wall.addWallListToSpringBody(wallList, sb, false);

        DataModelsFactory.getSceneTreeModel().fireSpringBodyListChanged();

        SA_Selection.clearSelection(scene);
        SA_Selection.addSpringBodyToSelection(sb, scene, false);

        return sb;
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Changing items/objects properties
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    // Masses -------------------------------------------------------------------
    static public void setSelectedMassesName(String value, Scene scene) {
        int i = 0;
        for (Mass m : scene.EC.selectionGroup.getMassList()) {
            String postfix = scene.EC.selectionGroup.getMassList().size()==1 ? "" : ""+i++;
            m.setName(value + postfix);
        }
    }
    static public void setSelectedMassesMass(double value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.setMass(value);
        }
    }

    static public void setSelectedMassesVelocity(Vec2d value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.setVelocity(value);
        }
    }

    static public void addSelectedMassesVelocity(Vec2d value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.getVelocity().add(value);
        }
    }

    static public void setSelectedMassesPosition(Vec2d value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.setPosition(value);
        }
    }
    static public void setSelectedMassesPositionX(double value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.getPosition().setX(value);
        }
    }
    static public void setSelectedMassesPositionY(double value, Scene scene) {
        for (Mass mass : scene.EC.selectionGroup.getMassList()) {
            mass.getPosition().setY(value);
        }
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Springs
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static public void setSelectedSpringsName(String value, Scene scene) {
        int i = 0;
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            String postfix = scene.EC.selectionGroup.getSpringList().size()==1 ? "" : ""+i++;
            spring.setName(value + postfix);
        }
    }
    static public void setSelectedSpringsKs(double value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setKs(value);
        }
    }

    static public void setSelectedSpringsKd(double value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setKd(value);
        }
    }

    static public void setSelectedSpringsKt(double value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setKt(value);
        }
    }

    static public void setSelectedSpringsTearable(boolean value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setTearable(value);
        }
    }

    static public void setSelectedSpringsAlive(boolean value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setAlive(value);
        }
    }

    static public void setSelectedSpringsStartLength(double value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setStartLength(value);
        }
    }

    static public void setSelectedSpringsStartLengthAsCurrent(double value, Scene scene) {
        for (Spring spring : scene.EC.selectionGroup.getSpringList()) {
            spring.setStartLength(spring.getVector().getMagnitude());
        }
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Rotary Springs
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static public void setSelectedRSpringsKs(double value, Scene scene) {
        for (RSpring rs : scene.EC.selectionGroup.getRSpringList()) {
            rs.setKs(value);
        }
    }

    static public void setSelectedRSpringsKd(double value, Scene scene) {
        for (RSpring rs : scene.EC.selectionGroup.getRSpringList()) {
            rs.setKd(value);
        }
    }

    static public void setSelectedRSpringsStartAngle(double value, Scene scene) {
        for (RSpring rs : scene.EC.selectionGroup.getRSpringList()) {
            rs.setStartAngle(value);
        }
    }

    static public void setSelectedRSpringsStartAngleAsCurrent(Scene scene) {
        for (RSpring rs : scene.EC.selectionGroup.getRSpringList()) {
            rs.recalculateStartAngle();
        }
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Torques
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static public synchronized void newTorque(Scene scene) {
        Torque t = new Torque(null, 0.);
        scene.getJETContext().addTorque(t);

        //CC.propertiesDialog.updateTorqueListModel();
        //CC.actionsDialog.updateUserInterface();

        DataModelsFactory.getTorquesListModel().fireTorquesListChanged();
    }

    static public synchronized void addTorque(Torque t, Scene scene) {
        scene.getJETContext().addTorque(t);
        DataModelsFactory.getTorquesListModel().fireTorquesListChanged();
    }

    static public void removeTorque(Torque t, Scene scene) {
        scene.getJETContext().removeTorque(t);
        DataModelsFactory.getTorquesListModel().fireTorquesListChanged();

        for (Action a : CC.AC.getActionList()) {
            if (a instanceof ActivateTorquesAction) {
                ((ActivateTorquesAction) a).removeTorque(t);
            } else if (a instanceof DeactivateTorquesAction) {
                ((DeactivateTorquesAction) a).removeTorque(t);
            }
        }
    }

    static public void setTorqueCenterMass(Torque t, Mass m) {
        t.setMass(m);
    }

    static public void bindMassesToTorque(Torque t, ArrayList<Mass> massList) {
        t.getMassList().addAll(massList);

        // TODO : update mass list in properties dialog.
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Materials
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static public synchronized void addNewMaterial(Scene scene) {
        int newCount = scene.getJETContext().materialsCount + 1;
        MaterialPair[][] newMatTable = new MaterialPair[newCount][newCount];

        for (int r = 0; r < scene.getJETContext().materialsCount; r++) {
            for (int c = 0; c < scene.getJETContext().materialsCount; c++) {
                newMatTable[r][c] = scene.getJETContext().materials[r][c];
            }
        }

        for (int r = 0; r < newCount; r++) {
            newMatTable[r][newCount - 1] = new MaterialPair();
        }

        for (int c = 0; c < newCount; c++) {
            newMatTable[newCount - 1][c] = new MaterialPair();
        }

        scene.getJETContext().materials = newMatTable;

        String[] newNamesTab = new String[newCount];

        for (int i = 0; i < scene.getJETContext().materialsCount; i++) {
            newNamesTab[i] = scene.getJETContext().materialNames[i];
        }
        newNamesTab[newCount - 1] = "Material_" + (newCount - 1);

        scene.getJETContext().materialNames = newNamesTab;
        scene.getJETContext().materialsCount++;

        CC.GUIC.materialsDialog.updateTable();
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * MainFrame buttons and stuff
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static public synchronized void setFolllowCamera(Scene scene, boolean value) {
        scene.EC.setFollowCamera(value);
        CC.GUIC.setFollowCameraButtonSelected(value);
    }

    static public synchronized void setDrawActionFrame(Scene scene, boolean value) {
        scene.GC.setDrawActionFrame(value);
        CC.GUIC.setDrawActionFrameButtonSelected(value);
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Engine springs
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//    static public synchronized void addSpringToEngineList(Spring spring, Scene scene) {
//        scene.getEngine().addSpringToEngineList(spring);
//    }

//    public static synchronized void removeSpringFromEngine(Spring spring, Scene scene) {
//        scene.getEngine().removeSpringFromEngineList(spring);
//    }

//    public static void removeSpringsFromEngine(ArrayList<Spring> list, Scene scene) {
//        Collection<Spring> springCol = scene.getEngine().getSpringListSync();
//        synchronized(springCol) {
//            for(Spring s : list)
//                springCol.remove(s);
//        }
//    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Engine rotary springs
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//    static public synchronized void addRSpringToEngineList(RSpring rSpring, Scene scene) {
//        scene.getEngine().addRSpringToEngineList(rSpring);
//    }
//
//    public static synchronized void removeRSpringFromEngine(RSpring rSpring, Scene scene) {
//        scene.getEngine().removeRSpringFromEngineList(rSpring);
//    }
//
//    public static synchronized void removeRSpringsFromEngine(ArrayList<RSpring> list, Scene scene) {
//        for(RSpring rs : list)
//            scene.getEngine().removeRSpringFromEngineList(rs);
//    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     * Actions
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    static synchronized public void addAction(Action a) {
        CC.AC.addAction(a);
        DataModelsFactory.getActionsListModel().fireAtcionsListChanged();
    }

    static synchronized public void removeAction(Action a) {
        CC.AC.removeAction(a);
        DataModelsFactory.getActionsListModel().fireAtcionsListChanged();
    }

    static synchronized public void bindActionToKeyPressActions(int keyCode, int actionIndex, Scene scene) {
        VKey vKey = scene.getVKeyboard().getKey(keyCode);
        Action action = CC.AC.getAction(actionIndex);

        vKey.getPressActions().add(action);
    }

    static synchronized public void bindActionToKeyReleaseActions(int keyCode, int actionIndex, Scene scene) {
        VKey vKey = scene.getVKeyboard().getKey(keyCode);
        Action action = CC.AC.getAction(actionIndex);

        vKey.getReleaseActions().add(action);
    }

    static synchronized public void bindActionToKeyPressActions(VKey vKey, int actionIndex) {
        Action action = CC.AC.getAction(actionIndex);

        vKey.getPressActions().add(action);
    }

    static synchronized public void bindActionToKeyReleaseActions(VKey vKey, int actionIndex) {
        Action action = CC.AC.getAction(actionIndex);

        vKey.getReleaseActions().add(action);
    }
}

